package com.bianpai.example;

import com.bianpai.core.*;
import com.bianpai.log.DatabaseFlowLogger;
import com.bianpai.log.FlowLogger;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * 简单流程示例
 */
public class SimpleFlowExample {
    
    public static void main(String[] args) {
        // 创建数据源（示例中使用模拟数据源）
        DataSource dataSource = createMockDataSource();
        
        // 创建日志记录器
        FlowLogger logger = new DatabaseFlowLogger(dataSource);
        
        // 创建流程引擎
        FlowEngine engine = new FlowEngine(logger);
        
        // 创建流程
        Flow flow = createSampleFlow();
        
        // 创建流程上下文
        FlowContext context = new FlowContext(flow.getId());
        context.setVariable("orderId", "ORD-001");
        context.setVariable("amount", 100.0);
        
        // 执行流程
        FlowEngine.FlowResult result = engine.execute(flow, context);
        
        // 处理结果
        if (result.isSuccess()) {
            System.out.println("流程执行成功！");
            System.out.println("订单状态: " + context.getVariable("orderStatus"));
        } else {
            System.out.println("流程执行失败: " + result.getMessage());
            if (result.getException() != null) {
                result.getException().printStackTrace();
            }
        }
    }
    
    /**
     * 创建示例流程
     * @return 流程
     */
    private static Flow createSampleFlow() {
        return FlowBuilder.create("order-process", "订单处理流程")
                .description("处理订单从创建到支付的完整流程")
                .addNode(new ValidateOrderNode("validate", "验证订单"))
                .addNode(new ReserveInventoryNode("reserve", "预留库存"))
                .addNode(new ProcessPaymentNode("payment", "处理支付"))
                .addNode(new UpdateOrderStatusNode("update-status", "更新订单状态"))
                .addNode(new SendNotificationNode("notify", "发送通知"))
                // 添加依赖关系
                .addDependency("reserve", "validate") // 预留库存依赖于验证订单
                .addDependency("payment", "reserve") // 处理支付依赖于预留库存
                .addDependency("update-status", "payment") // 更新状态依赖于处理支付
                .addDependency("notify", "update-status") // 发送通知依赖于更新状态
                // 使用并行执行策略
                .useParallelExecution()
                .build();
    }
    
    /**
     * 创建模拟数据源
     * @return 数据源
     */
    private static DataSource createMockDataSource() {
        // 这里返回一个模拟的数据源，实际应用中应该使用真实的数据源
        return new MockDataSource();
    }
    
    /**
     * 验证订单节点
     */
    static class ValidateOrderNode extends AbstractNode {
        public ValidateOrderNode(String id, String name) {
            super(id, name);
        }
        
        @Override
        public NodeResult execute(FlowContext context) {
            String orderId = (String) context.getVariable("orderId");
            System.out.println("验证订单: " + orderId);
            
            // 模拟验证逻辑
            if (orderId != null && orderId.startsWith("ORD-")) {
                return NodeResult.success("订单验证通过");
            } else {
                return NodeResult.failure("无效的订单ID");
            }
        }
    }
    
    /**
     * 预留库存节点
     */
    static class ReserveInventoryNode extends AbstractNode {
        public ReserveInventoryNode(String id, String name) {
            super(id, name);
        }
        
        @Override
        public NodeResult execute(FlowContext context) {
            String orderId = (String) context.getVariable("orderId");
            System.out.println("预留库存: " + orderId);
            
            // 模拟预留库存逻辑
            context.setVariable("inventoryReserved", true);
            return NodeResult.success("库存预留成功");
        }
        
        @Override
        public boolean rollback(FlowContext context) {
            String orderId = (String) context.getVariable("orderId");
            System.out.println("回滚库存预留: " + orderId);
            
            // 模拟回滚逻辑
            context.setVariable("inventoryReserved", false);
            return true;
        }
    }
    
    /**
     * 处理支付节点
     */
    static class ProcessPaymentNode extends AbstractNode {
        public ProcessPaymentNode(String id, String name) {
            super(id, name);
        }
        
        @Override
        public NodeResult execute(FlowContext context) {
            String orderId = (String) context.getVariable("orderId");
            Double amount = (Double) context.getVariable("amount");
            System.out.println("处理支付: " + orderId + ", 金额: " + amount);
            
            // 模拟支付逻辑
            Map<String, Object> paymentResult = new HashMap<>();
            paymentResult.put("transactionId", "TXN-" + System.currentTimeMillis());
            paymentResult.put("status", "SUCCESS");
            
            return NodeResult.success("支付处理成功", paymentResult);
        }
        
        @Override
        public boolean rollback(FlowContext context) {
            String orderId = (String) context.getVariable("orderId");
            System.out.println("回滚支付: " + orderId);
            
            // 模拟退款逻辑
            NodeResult paymentResult = context.getNodeResult(getId());
            if (paymentResult != null && paymentResult.isSuccess()) {
                String transactionId = (String) paymentResult.getData().get("transactionId");
                System.out.println("退款交易: " + transactionId);
            }
            
            return true;
        }
    }
    
    /**
     * 更新订单状态节点
     */
    static class UpdateOrderStatusNode extends AbstractNode {
        public UpdateOrderStatusNode(String id, String name) {
            super(id, name);
        }
        
        @Override
        public NodeResult execute(FlowContext context) {
            String orderId = (String) context.getVariable("orderId");
            System.out.println("更新订单状态: " + orderId);
            
            // 模拟更新状态逻辑
            context.setVariable("orderStatus", "PAID");
            return NodeResult.success("订单状态更新成功");
        }
    }
    
    /**
     * 发送通知节点
     */
    static class SendNotificationNode extends AbstractNode {
        public SendNotificationNode(String id, String name) {
            super(id, name);
        }
        
        @Override
        public NodeResult execute(FlowContext context) {
            String orderId = (String) context.getVariable("orderId");
            String status = (String) context.getVariable("orderStatus");
            System.out.println("发送通知: 订单 " + orderId + " 状态已更新为 " + status);
            
            // 模拟发送通知逻辑
            return NodeResult.success("通知发送成功");
        }
    }
    
    /**
     * 模拟数据源
     */
    static class MockDataSource implements DataSource {
        // 实现DataSource接口的方法，但实际不做任何事情
        // 这里省略了接口方法的实现，实际应用中应该使用真实的数据源
        
        @Override
        public java.sql.Connection getConnection() throws java.sql.SQLException {
            throw new UnsupportedOperationException("This is a mock DataSource for demonstration only");
        }
        
        @Override
        public java.sql.Connection getConnection(String username, String password) throws java.sql.SQLException {
            throw new UnsupportedOperationException("This is a mock DataSource for demonstration only");
        }
        
        // 其他接口方法的空实现
        @Override public java.io.PrintWriter getLogWriter() { return null; }
        @Override public void setLogWriter(java.io.PrintWriter out) {}
        @Override public void setLoginTimeout(int seconds) {}
        @Override public int getLoginTimeout() { return 0; }
        @Override public java.util.logging.Logger getParentLogger() { return null; }
        @Override public <T> T unwrap(Class<T> iface) { return null; }
        @Override public boolean isWrapperFor(Class<?> iface) { return false; }
    }
}